<?php

namespace App\Ad\Docking;

use App\Ad\MediaApi\MediaApiBase;
use App\Commons\CommonConstant;
use App\Datalog\AdMonitorLog;
use App\Models\AdMonitor;
use App\Models\AdPlan;
use App\Models\FirstupAd;
use App\Models\Firstups;
use App\Models\Log\LogAdMonitor;
use App\Models\Log\LogAdMonitorInfo;
use App\Models\Log\LogAdPostbackMedia;
use Illuminate\Http\Request;

// Uc-微信小程序
// 对接文档
// https://www.yuque.com/chaojihuichuan/hhcp03/cu861b
class UcXyx extends DockingBase
{
    // 点击监控参数
    protected $monitorParams = [
        'idfa'           => '{IDFA1}',            // idfa
        'idfa_md5'       => '{IDFA_SUM}',         // idfa转大写，计算md5，再转大写
        'imei_md5'       => '{IMEI_SUM}',         // imei原值转大写，计算md5，再转大写
        'imei_md52'      => '{IMEI_SUM1}',        // 直接取 32 位 md5sum
        'oaid'           => '{OAID}',             // oaid
        'oaid_md5'       => '{OAID_SUM}',         // 直接取 32 位 md5sum
        'oaid_md52'      => '{OAID_SUM1}',        // 原值转大写，计算 32 位 md5sum，再转大写
        'caid'           => '{CAID}',             // 经过 url encode 的字符串
        'ua'             => '{UA}',               // 代理信息
        'ip'             => '{IP}',               // 用户ip
        'time'           => '{UX_TS}',            // 点击时间 毫秒
        'callback_url'   => '{CALLBACK_URL}',     // 回传地址
        'callback_param' => '{CALLBACK_PARAM}',   // 回传参数
        'account_id'     => '{ACID}',             // 广告主id
        'adgroup_id'     => '{GID}',              // 广告组id
        'ad_id'          => '{AID}',              // 广告计划 ID
        'creative_id'    => '{CID}',              // 创意id
        'mac'            => '{MAC_SUM}',          // 保留 “:”，保持大写，取 32 位 md5sum，再转大写
        'android_id'     => '{ANDROIDID_SUM}',    // 保持大写，取 32 位 md5sum，再转大写
        'android_id2'    => '{ANDROIDID_SUM1}',   // 直接取 32 位 md5sum。
        'os'             => '{OS_ID}',            // 0 表示 iOS ,1 表示 Android,100 其他
        'model'          => '{MODEL1}',           // UA 中的设备机型，示例 iPhone13,2 进行urlencode
    ];

    // 转化类型映射
    protected $eventTypeMap = [
        CommonConstant::EVENT_FIRSTUP => '1',
        CommonConstant::EVENT_REG => '27',
        CommonConstant::EVENT_PAY => '1000',
    ];

    // 此接口由子类继承
    // 获得点击监控链接拼接参数
    public function getMonitorParams($device_type): string
    {
        return urldecode(http_build_query($this->monitorParams));
    }

    // 此接口由子类继承
    // 处理落地监控数据
    public function handleMonitorInfo(Request $request)
    {
        // 待匹配日志
        $params           = $request->all();
        $log              = LogAdMonitor::suffix(date('Ym'));
        $log->create_time = time();
        $log->plan_id     = $params['plan_id'];
        $log->ip          = $params['ip'] ?? '';
        $log->save();

        // 完整日志
        $info              = LogAdMonitorInfo::suffix(date('Ym'));
        $info->create_time = time();
        $info->plan_id     = $params['plan_id'];
        $info->monitor_id  = $log->id;
        $info->data        = json_encode($params, JSON_UNESCAPED_UNICODE);
        $info->save();

        // 落地日志
        AdMonitorLog::getInstance()->addLog($log, $info);

        return yqok();
    }

    // 此接口由子类继承
    // 是否可以基于ip去匹配数据
    public function needCheckUa()
    {
        return true;
    }

    /**
     * 此接口由子类继承
     * 根据媒体加密方式-生成对应的设备码，用于匹配
     * @param int      $device_type 设备类型
     * @param string[] $device_nums 设备码
     * @return array
     */
    public function getMonitorDeviceNum($device_type, $device_nums): array
    {
        $data = [];
        foreach ($device_nums as $key => $val) {
            switch ($key) {
                case 'click_id':
                    $data[$key] = $val;
                    break;
            }
        }

        return $data;
    }

    /**
     * 此接口由子类继承
     * 将用户行为进行api上报转化，如激活注册付费
     *
     * @param int $event_type 事件类型 如激活注册付费
     * @param AdMonitor $monitor
     * @param FirstupAd $firstup_ad
     * @param mixed $mod 事件对应的模型 激活 Firstup 注册 Users 付费 Orders
     * @return int 处理结果状态
     */
    public function postbackToMedia($event_type, AdMonitor $monitor, FirstupAd $firstup_ad, $mod): int
    {
        // 此事件不需要上报
        if (!isset($this->eventTypeMap[$event_type])) {
            return LogAdPostbackMedia::STATUS_NONEED;
        }

        $plan = AdPlan::find($firstup_ad->plan_id);

        // 如果非API自上报则无需处理
        if ($plan['access_type'] != AdPlan::ACCESS_TYPE_API) {
            return LogAdPostbackMedia::STATUS_NOTAPI;
        }

        $monitor_data = json_decode($monitor->data, true);
        $firstup = Firstups::find($firstup_ad->firstup_id);

        $params = [
            'uctrackid'  => $firstup->click_id,
            'type'       => $this->eventTypeMap[$event_type],
            'event_time' => $mod->create_time * 1000,
        ];

        // 如果是充值加传金额
        $is_pay = $event_type == CommonConstant::EVENT_PAY;
        if ($is_pay) {
            $params['money'] = $mod->call_money;
        }

        // 不存在callback
        if (!isset($monitor_data['callback_url'])) {
            return LogAdPostbackMedia::STATUS_NOCALLBACK;
        }

        // $url = urldecode($monitor_data['callback_url']);

        //更新回调的服务器地址
        $url = "https://huichuan.uc.cn/callback/appapi";
        $res  = MediaApiBase::getInstance()->curl($url, $params, false, true);

        if ($res[0] != 200) {
            return LogAdPostbackMedia::STATUS_FAIL;
        }

        return LogAdPostbackMedia::STATUS_SUCC;
    }

    // 此接口由子类继承
    // 匹配成功后补齐监控数据
    public function supplementMonitorInfo(FirstupAd $firstup_ad, AdMonitor $monitor)
    {
        $data = json_decode($monitor->data, true);

        $firstup_ad->advertiser_id = intval($data['account_id'] ?? 0);   // 广告主id
        $firstup_ad->adgroup_id    = intval($data['adgroup_id'] ?? 0);   // 计划id
        $firstup_ad->ad_id         = intval($data['ad_id'] ?? 0);        // 单元id
        $firstup_ad->creative_id   = intval($data['creative_id'] ?? 0);  // 创意id
    }
}
